﻿using System;
using System.Drawing;
using System.Windows.Forms;
using AutomatedDecisionMaking.Class;
using AutomatedDecisionMaking.GUI.BayesWindow;
using AutomatedDecisionMaking.GUI.CarefulChoiceWindow;
using AutomatedDecisionMaking.GUI.HelpWindows;
using AutomatedDecisionMaking.GUI.LaplaceWindow;
using AutomatedDecisionMaking.GUI.MOWmaxWindow;
using AutomatedDecisionMaking.GUI.MOWminWindow;
using AutomatedDecisionMaking.GUI.MaxiMaxWindow;
using AutomatedDecisionMaking.GUI.MinRegretWindow;
using AutomatedDecisionMaking.GUI.MiniMaxWindow;
using AutomatedDecisionMaking.UserControls;

namespace AutomatedDecisionMaking.GUI.MainWindow
{
    public partial class FrmMainWindow : Form
    {
        #region Pola prywtne
        private bool _mListScenarioClicked;             // Informacja o tym czy kliknięto listę scenariuszy
        private bool _mListDecisionClicked;             // Informacja o tym czy kliknięto listę decyzji
        private readonly FrmAddDescription _mFrmAdd;    // Okno dodawanie opisu problemu
        #endregion

        #region Konstruktor i podstawowe właściwości okna
        /// <summary>
        /// Konstrukotr okna głównego
        /// </summary>
        public FrmMainWindow()
        {
            InitializeComponent();
            _mFrmAdd = new FrmAddDescription();
            _mListScenarioClicked = false;
            _mListDecisionClicked = false;


        }
        

        /// <summary>
        /// Uruchomienie zakładki z informacja mi o programie.
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void oProgramieToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmAbout _frmAbout = new FrmAbout();
            _frmAbout.ShowDialog();
        }

        /// <summary>
        /// Uruchomienie zakładki z instrukcją użytkownia.
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void obslugaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmUserManual _frmUserManual = new FrmUserManual();
            _frmUserManual.ShowDialog();
        }

        /// <summary>
        /// Zamknięcie programu.
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Metoda wywoływana w momencie uruchamiania programu.
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void FrmMainWindow_Load(object sender, EventArgs e)
        {
                            //Zadanie
            //Parasole
            //Umbrellas();
            //Drużyny
            Teams();


           DataGridView_DecisionMatrix.DefaultCellStyle.Font = new Font("Microsoft Sans Serif", 8);
           DataGridView_DecisionMatrix.ColumnHeadersDefaultCellStyle.Font = new Font("Microsoft Sans Serif", 8, FontStyle.Bold);
           DataGridView_DecisionMatrix.RowHeadersDefaultCellStyle.Font = new Font("Microsoft Sans Serif", 8, FontStyle.Bold);
            

        }

        void Umbrellas()
        {
            ListBox_Scenario.Items.Add("S1 - Będzie padał deszcz");
            ListBox_Scenario.Items.Add("S2 - Nie będzie padał deszcz");

            ListBox_Decision.Items.Add("D1 - Biorę parasol");
            ListBox_Decision.Items.Add("D2 - Nie biorę parasola");

            DataGridView_DecisionMatrix.Columns.Add("S1", "S1");
            DataGridView_DecisionMatrix.Columns.Add("S2", "S2");

            DataGridView_DecisionMatrix.Rows.Add(8, 1);
            DataGridView_DecisionMatrix.Rows.Add(2, 10);
            DataGridView_DecisionMatrix.Rows[0].HeaderCell.Value = "D1";
            DataGridView_DecisionMatrix.Rows[1].HeaderCell.Value = "D2";
        }
        
        void Teams()
        {
            ListBox_Scenario.Items.Add("S1 - Udział w finale Real Madryt");
            ListBox_Scenario.Items.Add("S2 - Udział w finale AC Milan");
            ListBox_Scenario.Items.Add("S3 - Udział w finale Bayern Monachium");
            ListBox_Scenario.Items.Add("S4 - Udział w finale Manchester United");

            ListBox_Decision.Items.Add("D1 - Inwestuję w Real");
            ListBox_Decision.Items.Add("D2 - Inwestuję w Milan");
            ListBox_Decision.Items.Add("D3 - Inwestuję w Bayern");
            ListBox_Decision.Items.Add("D4 - Inwestuję w Manchester");

            DataGridView_DecisionMatrix.Columns.Add("S1", "S1");
            DataGridView_DecisionMatrix.Columns.Add("S2", "S2");
            DataGridView_DecisionMatrix.Columns.Add("S3", "S3");
            DataGridView_DecisionMatrix.Columns.Add("S4", "S4");

            DataGridView_DecisionMatrix.Rows.Add(4, 2, 2, 2);
            DataGridView_DecisionMatrix.Rows.Add(2, 4, 2, 2);
            DataGridView_DecisionMatrix.Rows.Add(2, 2, 4, 2);
            DataGridView_DecisionMatrix.Rows.Add(2, 2, 2, 4);

            DataGridView_DecisionMatrix.Rows[0].HeaderCell.Value = "D1";
            DataGridView_DecisionMatrix.Rows[1].HeaderCell.Value = "D2";
            DataGridView_DecisionMatrix.Rows[2].HeaderCell.Value = "D3";
            DataGridView_DecisionMatrix.Rows[3].HeaderCell.Value = "D4";
        }
        #endregion

        #region Macierz decyzji
        /// <summary>
        /// Metoda wykonywana gdy użytkownik zakończy edycję tabeli
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void DataGridView_DecisionMatrix_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                double doubleValue;
                string cellValue = DataGridView_DecisionMatrix.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
                if (!(double.TryParse(cellValue, out doubleValue)))
                {
                    MessageBox.Show("Wprowadzona wartość musi być liczbą!",
                                    "INFORMACJA!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    DataGridView_DecisionMatrix.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                }

            }
            catch (NullReferenceException exception){}
        }

        /// <summary>
        /// Sprawdzenie czy dane w macierzy sa poprawne
        /// </summary>
        private void CheckTableConsistency()
        {
            for (int i = 0; i < DataGridView_DecisionMatrix.Rows.Count; ++i)
            {
                for (int j = 0; j < DataGridView_DecisionMatrix.Columns.Count; ++j)
                {
                    var cellValue = DataGridView_DecisionMatrix.Rows[i].Cells[j].Value;
                    if (cellValue == null)
                        throw new ArgumentNullException("Nie wprowadzono danych we wszystkie komórki!");
                }
            }
        }

        /// <summary>
        /// Gdy usuwany wiersz macierz to i usuwany jest wiersz na menu decyzji
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void DataGridView_DecisionMatrix_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            ListBox_Decision.Items.RemoveAt(e.Row.Index);
        }
        #endregion

        #region Edycja scenariuszy i decyzji
        /// <summary>
        /// Kliknięcie menu scenariuszy
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void ListBox_Scenario_Click(object sender, EventArgs e)
        {
            _mListScenarioClicked = true;
            _mListDecisionClicked = false;
        }

        /// <summary>
        /// Kliknięcie menu decyzji
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void ListBox_Decision_Click(object sender, EventArgs e)
        {
            _mListDecisionClicked = true;
            _mListScenarioClicked = false;
        }

        /// <summary>
        /// Dodawanie scenariuszy lub decyzji
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void Button_Add_Click(object sender, EventArgs e)
        {
            int columnsNo = this.DataGridView_DecisionMatrix.Columns.Count;
            int rowsNo = this.DataGridView_DecisionMatrix.Rows.Count;

            if(_mListScenarioClicked)
            {
                _mFrmAdd.Text = "Scenariusze - OPIS";
                _mFrmAdd.TextBox_Description.Text = "";
                if (_mFrmAdd.ShowDialog() == DialogResult.OK)
                {
                    ListBox_Scenario.Items.Add(_mFrmAdd.TextBox_Description.Text);
                    this.DataGridView_DecisionMatrix.Columns.Add("S" + (columnsNo + 1), "S" + (columnsNo + 1));

                }
            }
            else if(_mListDecisionClicked && ListBox_Scenario.Items.Count > 0)
            {

                _mFrmAdd.Text = "Decyzje - OPIS";
                _mFrmAdd.TextBox_Description.Text = "";
                if (_mFrmAdd.ShowDialog() == DialogResult.OK)
                {
                    ListBox_Decision.Items.Add(_mFrmAdd.TextBox_Description.Text);
                    this.DataGridView_DecisionMatrix.Rows.Add();
                    this.DataGridView_DecisionMatrix.Rows[rowsNo].HeaderCell.Value = "D" + (rowsNo + 1);
                }
            }
            else if(_mListDecisionClicked && ListBox_Scenario.Items.Count < 1)
                MessageBox.Show("Najpierw nalezy wprowadzić scenariusze!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);


            else
                MessageBox.Show("Nie zaznaczono żadnego okna!\nZaznacz okno scenariuszy lub decyzji aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);


           // _mListDecisionClicked = false;
            //_mListScenarioClicked = false;
        }

        /// <summary>
        /// Edytowanie scenariuszy lub decyzji
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void Button_Edit_Click(object sender, EventArgs e)
        {
            if (ListBox_Scenario.SelectedIndex > -1 && _mListScenarioClicked)
            {
                _mFrmAdd.Text = "Scenariusze - OPIS";
                _mFrmAdd.TextBox_Description.Text = ListBox_Scenario.Items[ListBox_Scenario.SelectedIndex].ToString();
                if (_mFrmAdd.ShowDialog() == DialogResult.OK)
                    ListBox_Scenario.Items[ListBox_Scenario.SelectedIndex] = _mFrmAdd.TextBox_Description.Text;
            }
            else if (ListBox_Decision.SelectedIndex > -1 && _mListDecisionClicked)
            {
                _mFrmAdd.Text = "Decyzje - OPIS";
                _mFrmAdd.TextBox_Description.Text = ListBox_Decision.Items[ListBox_Decision.SelectedIndex].ToString();
                if (_mFrmAdd.ShowDialog() == DialogResult.OK)
                    ListBox_Decision.Items[ListBox_Decision.SelectedIndex] = _mFrmAdd.TextBox_Description.Text;
            }
            else
                MessageBox.Show(
                    "Nie zaznaczono żadnego scenariusza lub decyzji do modyfikacji!\nZaznacz scenariusz lub decyzję aby kontynuować!",
                    "INFORMACJA!",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);


            _mListDecisionClicked = false;
            _mListScenarioClicked = false;

        }

        /// <summary>
        /// Usuwanie scenariuszy lub decyzji
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void Button_Delete_Click(object sender, EventArgs e)
        {
            if (ListBox_Scenario.SelectedIndex > -1 && _mListScenarioClicked)
            {
                if (ListBox_Scenario.Items.Count > 1)
                {
                    this.DataGridView_DecisionMatrix.Columns.RemoveAt(ListBox_Scenario.SelectedIndex);
                    ListBox_Scenario.Items.RemoveAt(ListBox_Scenario.SelectedIndex);
                }
                else
                    MessageBox.Show("Musi być zdefiniowany przynajmniej jeden scenariusz!",
                                "UWAGA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
            else if (ListBox_Decision.SelectedIndex > -1 && _mListDecisionClicked)
            {
                this.DataGridView_DecisionMatrix.Rows.RemoveAt(ListBox_Decision.SelectedIndex);
                ListBox_Decision.Items.RemoveAt(ListBox_Decision.SelectedIndex);
            }
            else
                MessageBox.Show("Nie zaznaczyłeś żadnego scenariusza/decyzji do usunięcia",
                                "UWAGA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            
        }

        /// <summary>
        /// Kliknięcie przycisku delete na liście scenariuszy
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void ListBox_Scenario_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                var index = ListBox_Scenario.SelectedIndex;
                if (index > -1)
                {
                    if (ListBox_Scenario.Items.Count > 1)
                    {
                        ListBox_Scenario.Items.RemoveAt(index);
                        DataGridView_DecisionMatrix.Columns.RemoveAt(index);
                    }
                    else
                        MessageBox.Show("Musi być zdefiniowany przynajmniej jeden scenariusz!",
                                "UWAGA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
                }
            }
        }

        /// <summary>
        /// Kliknięcie przycisku delete na liście decyzji
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void ListBox_Decision_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                var index = ListBox_Decision.SelectedIndex;
                if (index > -1)
                {
                    ListBox_Decision.Items.RemoveAt(index);
                    DataGridView_DecisionMatrix.Rows.RemoveAt(index);
                }
            }
        }

        
        #endregion

        #region Podejmowanie decycji

        #region Podejmowanie decyzji w warunkach niepewności
        /// <summary>
        /// Wykonanie kryterium MaxiMax
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_MaxiMax_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);
                DecisionMatrix decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var m_FrmMaxiMax = new FrmMaxiMax(decisionMatrix);
                m_FrmMaxiMax.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
            
        }

        /// <summary>
        /// Wykonanie kryterium MiniMax
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_MiniMax_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);

                DecisionMatrix decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var m_FrmMaxiMax = new FrmMiniMax(decisionMatrix);
                m_FrmMaxiMax.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }


        }

        /// <summary>
        /// Wykonanie kryterium wyboru ostrożnego
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_CarefulChoice_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);
                DecisionMatrix decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var m_FrmCarefulChoice = new FrmCarefulChoice(decisionMatrix);
                m_FrmCarefulChoice.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// Wykonanie kryterium najmniejszego żalu
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_MinRegret_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);

                DecisionMatrix decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var FrmMinRegret = new FrmMinRegret(decisionMatrix);
                FrmMinRegret.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }

        }

        /// <summary>
        /// Wykonanie kryterium laplace'a
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_Laplace_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);

                DecisionMatrix decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var FrmLaplace = new FrmLaplace(decisionMatrix);
                FrmLaplace.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
        }
        #endregion

        #region Podejmowanie decyzji w warunkach ryzyka
        /// <summary>
        /// Wykonanie kryterium maksimum oczekiwanego żalu
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_MaxRegretMOW_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);

                DecisionMatrix decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var FrmMaxMOW = new FrmMaxMOW(decisionMatrix);
                FrmMaxMOW.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }

        }

        /// <summary>
        /// Wykonanie kryterium minimum oczekiwanego żalu
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_MinRegretMOW_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);

                var decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var FrmMinMOW = new FrmMinMOW(decisionMatrix);
                FrmMinMOW.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
        }
        #endregion

        #region Podejmowanie dezycji w warunkach częściowej informacji
        /// <summary>
        /// Wykonanie kryterium bayesa
        /// </summary>
        /// <param name="sender">Obiekt wysyłający zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenia</param>
        private void MenuItem_Bayes_Click(object sender, EventArgs e)
        {
            try
            {
                CheckTableConsistency();
                var matrix = DataConverter.DataGridViewToList(DataGridView_DecisionMatrix);
                var scenario = DataConverter.ListBoxToList(ListBox_Scenario);
                var decision = DataConverter.ListBoxToList(ListBox_Decision);

                var decisionMatrix = new DecisionMatrix(matrix, scenario, decision);
                var FrmBayes = new FrmBayes(decisionMatrix);
                FrmBayes.ShowDialog();
            }
            catch (ArgumentNullException exception)
            {
                MessageBox.Show("Niektóre pola macierzy decyzji pozostały puste!\nUzupełnij je, aby kontynuować!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
        }
        #endregion

        #endregion

    }
}
